package com.xcn.dsxm.main_public.database.dao.impl;

import com.xcn.dsxm.main_public.database.config.MyBatisMapper;
import com.xcn.dsxm.main_public.database.config.MyBatistType;
import com.xcn.dsxm.main_public.database.dao.DbDao_xcn_admin;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;

@Repository("dbDaoImpl_xcn_admin")
public class DbDaoImpl_xcn_admin extends SqlSessionDaoSupport implements DbDao_xcn_admin {


    //Mybatis取消了自动注入SqlSessionFactory 和 SqlSessionTemplate 需要手动 set 一下
    @Resource
    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory_xcn_admin) {
        super.setSqlSessionFactory(sqlSessionFactory_xcn_admin);
    }

    @Override
    public int insert(String sql) throws Exception {
        return this.getSqlSession().insert(MyBatisMapper.Default + "insertSql", sql);
    }

    @Override
    public int insert(String mybatisId, HashMap<String, Object> params) throws Exception {
        return this.getSqlSession().insert(mybatisId, params);
    }

    @Override
    public int delete(String sql) throws Exception {
        return this.getSqlSession().delete(MyBatisMapper.Default + "deleteSql", sql);
    }

    @Override
    public int delete(String mybatisId, HashMap<String, Object> params) throws Exception {
        return this.getSqlSession().delete(mybatisId, params);
    }

    @Override
    public int update(String sql) throws Exception {
        return this.getSqlSession().delete(MyBatisMapper.Default + "updateSql", sql);
    }

    @Override
    public int update(String mybatisId, HashMap<String, Object> params) throws Exception {
        return this.getSqlSession().delete(mybatisId, params);
    }

    @Override
    public List<HashMap<String, Object>> more(String sql) throws Exception {
        return this.getSqlSession().selectList(MyBatisMapper.Default + "selectSql", sql);
    }

    @Override
    public List<HashMap<String, Object>> more(String mybatisId, HashMap<String, Object> params) throws Exception {
        return this.getSqlSession().selectList(mybatisId, params);
    }

    /**
     * 事务 如果在方法内添加 try-catch 模块，则异常直接被模块捕获，不会激发SpringMvc的事务管理
     * 如果有结果返回值为 0 ，直接 throw 一个异常被 SpringMvc 捕获即可，SpringMvc 会自动执行事务回滚
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, transactionManager = "transactionManager_bx_member")
    public int transaction(List<String> sqlArr) throws Exception {

        int result = 0;
        try {
            for (String sql : sqlArr) {
                String targetSql = sql.toLowerCase().trim();

                if (targetSql.startsWith("insert")) {
                    result += this.insert(targetSql);
                    continue;
                }

                if (targetSql.startsWith("delete")) {
                    result += this.delete(targetSql);
                    continue;
                }

                if (targetSql.startsWith("update")) {
                    result += this.update(targetSql);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("事务执行过程中出错 回滚 transaction");
        }

        return result;
    }

    /**
     * 事务 如果在方法内添加 try-catch 模块，则异常直接被模块捕获，不会激发SpringMvc的事务管理
     * 如果有结果返回值为 0 ，直接 throw 一个异常被 SpringMvc 捕获即可，SpringMvc 会自动执行事务回滚
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, transactionManager = "transactionManager_bx_member")
    public int transactions(HashMap<String, Object>... sqlArr) throws Exception {
        int result = 0;

        for (HashMap<String, Object> item : sqlArr) {
            if (!item.containsKey(MyBatistType.mybatisId)) {
                return -1;
            }
            if (!item.containsKey(MyBatistType.mybatisType)) {
                return -1;
            }

            String mybatisId = (String) item.get(MyBatistType.mybatisId);
            String mybatisType = (String) item.get(MyBatistType.mybatisType);

            item.remove(MyBatistType.mybatisId);
            item.remove(MyBatistType.mybatisType);

            switch (mybatisType) {
                case MyBatistType.INSERT: {
                    result += this.insert(mybatisId, item);
                }
                break;
                case MyBatistType.DELETE: {
                    result += this.delete(mybatisId, item);
                }
                break;
                case MyBatistType.UPDATE: {
                    result += this.update(mybatisId, item);
                }
                break;
            }
        }

        return result;
    }

    /**
     * 事务 如果在方法内添加 try-catch 模块，则异常直接被模块捕获，不会激发SpringMvc的事务管理
     * 如果有结果返回值为 0 ，直接 throw 一个异常被 SpringMvc 捕获即可，SpringMvc 会自动执行事务回滚
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, transactionManager = "transactionManager_bx_member")
    public int transactions(List<HashMap<String, Object>> sqlArr) throws Exception {
        int result = 0;

        for (HashMap<String, Object> item : sqlArr) {
            if (!item.containsKey(MyBatistType.mybatisId)) {
                return -1;
            }
            if (!item.containsKey(MyBatistType.mybatisType)) {
                return -1;
            }

            String mybatisId = (String) item.get(MyBatistType.mybatisId);
            String mybatisType = (String) item.get(MyBatistType.mybatisType);

            item.remove(MyBatistType.mybatisId);
            item.remove(MyBatistType.mybatisType);

            switch (mybatisType) {
                case MyBatistType.INSERT: {
                    result += this.insert(mybatisId, item);
                }
                break;
                case MyBatistType.DELETE: {
                    result += this.delete(mybatisId, item);
                }
                break;
                case MyBatistType.UPDATE: {
                    result += this.update(mybatisId, item);
                }
                break;
            }
        }

        return result;
    }

}
